/*
 * Copyright (c) Jan Šlahora (${USER}) - 2012.
 * Created in IntelliJ IDEA 10.5
 */

package statistics.tests;

import com.sun.xml.internal.bind.v2.runtime.unmarshaller.XsiNilLoader;

import java.sql.Array;
import java.util.ArrayList;
import java.util.HashMap;

/*
*   File ATest 
*   in package statistics.tests
*   was created by slaha
*   on 28.3.12 at 22:02.
*
*/
public class ATest {
  final static String ni = "ni";
  final static String Xi = "Xi";
  final static String prumXi = "prumXi";
  final static String sumaXij = "sumaXij";
  final static String si2 = "si2";
  final static String lnSi2 = "lnSi2";


  ArrayList<Mereni> mereni;

  public ATest() {
    this.mereni = new ArrayList<>();
  }

  public void add(ArrayList<Double> hodnoty, String jmeno) {
    mereni.add(new Mereni(hodnoty, (mereni.size() + 1), jmeno));
  }

  public void add(ArrayList<Double> hodnoty) {
    mereni.add(new Mereni(hodnoty, (mereni.size() + 1), null));
  }

  //////////////////////////////////////////////////////////////
  //   Získávání hodnot                                       //
  //////////////////////////////////////////////////////////////


  public ArrayList<Mereni> getMereni() {
    return mereni;
  }

  public int getK() {
    return mereni.size();
  }

  public int getN() {
    int n = 0;
    for (Mereni mereni : this.mereni) {
      n += mereni.getHodnoty().size();
    }

    return n;
  }

  public double getNi(int i) {
    return mereni.get(i).getHodnoty().size();
  }

  public double getSi2(int i) {
    return mereni.get(i).getCharakteristiky().get(si2);
  }

  public double getlnSi2(int i) {
    double si = getSi2(i);
    return Math.log(si);
  }

  public double getPrumXi(int i) {
    return mereni.get(i).getCharakteristiky().get(prumXi);
  }

  public double dejCelkoveSi2() {
    double suma = 0d;
    for (int i = 0; i < getK(); i++) {
      double prumer = getPrumXi(i);

      for (int j = 0; j < getNi(i); j++) {
        double hodnota = getMereni().get(i).getHodnoty().get(j);
        double d = hodnota - prumer;
        suma += Math.pow(d, 2);
      }
    }
    return (suma / (getN() - 1));
  }

  public ArrayList<String> getJmena() {
    ArrayList<String> jmena = new ArrayList<>();

    for (Mereni mereni : this.mereni) {
      jmena.add(mereni.jmeno);
    }

    return jmena;
  }

  public boolean remove(String jmeno) {
    Mereni del = null;
    for (Mereni m : mereni) {
      if (m.getJmeno().equals(jmeno)) {
        del = m;
        break;
      }
    }
    if (del != null) {
      mereni.remove(del);
      return true;
    }
    else {
      return false;
    }
  }

  public class Mereni implements Runnable {

    private ArrayList<Double> hodnoty;
    private HashMap<String, Double> charakteristiky;
    private int cisloVyberu;
    private String jmeno;


    private Mereni(ArrayList<Double> hodnoty, int cisloVyberu, String jmeno) {
      charakteristiky = new HashMap<>();
      this.hodnoty = hodnoty;
      this.cisloVyberu = cisloVyberu;
      this.jmeno = jmeno;
      this.run();
    }

    @Override
    public void run() {
      //..ni
      charakteristiky.put(ni, (double) hodnoty.size());

      //..průměr xi
      charakteristiky.put(prumXi, vypoctiPrumer());

      //..rozptyl Rozptyl
      charakteristiky.put(si2, vypoctiRozptyl());
    }


    private double vypoctiPrumer() {
      double sumaXi = 0d;

      for (double d : this.hodnoty) {
        sumaXi += d;
      }

      return (sumaXi / charakteristiky.get(ni));
    }

    private double vypoctiRozptyl() {
      double suma = 0;
      double rozptyl = ((double) 1.0d) / (hodnoty.size() - 1);

      double prumer = charakteristiky.get(prumXi);
      for (double d : hodnoty) {
        double rozdil = d - prumer;
        suma += Math.pow(rozdil, 2);
      }

      rozptyl *= suma;
      //rozptyl = Math.sqrt(rozptyl);

      //System.out.println(rozptyl);

      return rozptyl;
    }

    public ArrayList<Double> getHodnoty() {
      return hodnoty;
    }

    public HashMap<String, Double> getCharakteristiky() {
      return charakteristiky;
    }

    public String getJmeno() {
      return jmeno;
    }
  }



}
